<?php

namespace App\Common\Traits\Model;

use Illuminate\Database\Eloquent\Builder;

trait ModelSearchTrait
{
    //单模型搜索
    public function singleModelSearch($request,$model,$conditions):object{
        foreach ($conditions as $con){
            if($request->filled($con[0])){
                $column=$con[0];
                if($con[1]=='like'){
                    $keyword=$this->keywordTransform($request->$column);
                    $model=$model->where($column,$con[1],'%'.$keyword.'%');
                }elseif ($con[1]=='in'){
                    $model=$model->whereIn($column,$request->$column);
                }elseif ($con[1]=='between'){
                    $between=$this->getTimeBetween($request,$column);
                    if(!empty($between)){
                        $model=$model->whereBetween($column,$between);
                    }
                }else{
                    $model=$model->where($column,$con[1],$request->$column);
                }
            }
        }
        return $model;
    }

    //关联模型搜索
    public function relatedModelSearch($request,$model,$conditions):object{
        foreach ($conditions as $relation=>$con){
            if($this->hasRelation($request,$con)){
                $model=$model->whereHas($relation, function (Builder $query) use($request,$con) {
                    foreach ($con as $item){
                        $column=$item[0];
                        if($request->filled($column)){
                            if($item[1]=='like'){
                                $keyword=$this->keywordTransform($request->$column);
                                $query->where($column,$item[1],'%'.$keyword.'%');
                            }elseif ($item[1]=='in'){
                                $query->whereIn($column,$request->$column);
                            }elseif($item[1]=='between'){
                                $between=$this->getTimeBetween($request,$column);
                                if(!empty($between)) {
                                    $query->whereBetween($column, $between);
                                }
                            }else{
                                $query->where($column,$item[1],$request->$column);
                            }
                        }
                    }
                });
            }
        }
        return $model;
    }

    //转义 %
    public function keywordTransform($keyword):string{
        if(stristr($keyword,'%')){
            return str_replace('%','\%',$keyword);
        }
        return $keyword;
    }

    //时间段搜索
    public function timeBetweenSearch($request,$model,$conditions):object{
        foreach ($conditions as $v){
            if($request->filled($v[0])) {
                $column = $v[0];
                $timeBetween=$this->getTimeBetween($request,$column,$v[1]??null);
                if(!empty($timeBetween)){
                    $model=$model->where($column,'>=',$timeBetween[0])->where($column,'<=',$timeBetween[1]);
                }
            }
        }
        return $model;
    }

    //是否需要搜索这种关联
    public function hasRelation($request,$con):bool{
        foreach ($con as $item){
            $column=$item[0];
            if($request->filled($column)){
                return true;
            }
        }
        return false;
    }

    //分离开始和结束时间
    public function getTimeBetween($request,$column,$seperator=null):array{
        $timeBetween=explode($seperator??",",$request->$column);
        if(count($timeBetween)!=2){
            return [];
        }
        return [
            $timeBetween[0],
            $timeBetween[1],
        ];
    }

    //多选搜索
    public function multiSelectSearch($request,$model,$multiSelectCondition){
        foreach ($multiSelectCondition as $con){
            $column=$con[0];
            if($request->filled($column)){
                $model=$model->where(function ($query)use($request,$column,$con){
                    $i=0;
                    $keywords=explode(',',$request->$column);
                    foreach ($keywords as $keyword){
                        $keyword=$this->keywordTransform($keyword);
                        if($i==0){
                            $query->where($column,$con[1],'%'.$keyword.'%');
                        }else{
                            $query->orWhere($column,$con[1],'%'.$keyword.'%');
                        }
                        $i++;
                    }
                });
            }
        }
        return $model;
    }

}
